class Thumbnail < ActiveRecord::Base
  #require 'Image'
  
  CACHE = true
  CACHE_PATH = "#{RAILS_ROOT}/tmp/cache/thumbnails"
  CACHE_MAX_AGE = 2.weeks
  SIZING_OPTIONS = ['noscale', 'scale', 'crop']
  
  attr_accessor :src_image, :resized_image, :width, :height, :sizing
  
  def initialize(image_path)
    #default values
    self.sizing = 'scale'
  
    self.load(image_path)
  end
  
  def load(image_path)
    @src_image = Image.new(image_path)
  end
  
  def sizing=(sizing_option)
    return if sizing_option.nil?
    
    #Als het een juiste optie is, zet de instance variabele dan goed
    if SIZING_OPTIONS.include? sizing_option.to_s
      instance_variable_set :@sizing, sizing_option
    else
      (raise Exception, 'This is not an corect sizing_option')
    end
  end
  
  def width=(new_width)
    aspectratio = @src_image.aspectratio
    new_width = new_width.to_i
    
    if @sizing == 'noscale' || @sizing == 'crop'
      instance_variable_set :@width, new_width
    elsif
      new_height = (new_width / aspectratio).to_i
      instance_variable_set :@width, new_width
      instance_variable_set :@height, new_height
    end
  end
  
  def height=(new_height)
    aspectratio = @src_image.aspectratio
    new_height = new_height.to_i
    
    if @sizing == 'noscale' || @sizing == 'crop'
      instance_variable_set :@height, new_height
    elsif
      new_width = (new_height / aspectratio).to_i
      instance_variable_set :@width, new_width
      instance_variable_set :@height, new_height
    end
  end
  
  def width
    @width.to_i > 0 ? @width.to_i : @src_image.width
  end
  
  def height
    @height.to_i > 0 ? @height.to_i : @src_image.height
  end
  
  def resize_ratio
    width = self.width
    height = self.height
    aspectratio = self.aspectratio
  
    if aspectratio > 1 #Het is breder dan hoger
      resize_ratio = width.to_f / @src_image.width.to_f
    elsif #Het is hoger dan breder
      resize_ratio = (height.to_f / @src_image.height.to_f)
    end
    
    resize_ratio = 1 if resize_ratio.to_f == 0
    
    return resize_ratio
    
    #resize_ratio = 1 if resize_ratio.to_i > 1 && enlarge == false
  end
  
  def method_missing(methId, *args)
    @src_image.send(methId, *args)
  end
  
  def resize
    if @sizing == 'noscale'
      @resized_image.resize(w, h)
    elsif @sizing == 'scale'
      @resized_image = @src_image.resize(self.resize_ratio)
    else
      raise Exception, 'Cropping is not supported'
    end
    
    if CACHE
      cache_image
      cleanup_cache_images
    end 
  end
  
  def to_blob
    if has_cache?
      load_cache_image
    else
      resize
    end
    
    return @resized_image.to_blob
    
  end
  
  def has_cache?
    File.exists? cached_filename_with_path
    #get_all_cached_files.length > 0
  end
  
  def cache_image
    check_cache_dir
  
    #Write @resized_image to the cache_path
    @resized_image.write cached_filename_with_path
  end
  
  def load_cache_image
    @resized_image = Image.new(cached_filename_with_path)
  end
  
  def cached_filename(with_date = true)
    require 'digest/md5'
    extension = @src_image.extension
    timestamp = @src_image.cdate.to_i
    width = self.width
    height = self.height
    filename_md5 = Digest::MD5.hexdigest(@src_image.filename)
    
    if (with_date == false)
      timestamp = '*'
    end
    
    "thumb_#{width}x#{height}_#{filename_md5}_#{timestamp}.#{extension}"
  end
  
  def get_all_cached_files
    require 'find'
  
    pattern = CACHE_PATH + '/' + cached_filename(false)
    Dir.glob pattern
  end
  
  def cached_filename_with_path
    return CACHE_PATH + '/' + cached_filename 
  end
  
  def check_cache_dir
    if !File.exists? CACHE_PATH
      Dir.mkdir CACHE_PATH
    end
  end
  
  def cleanup_cache_images
    cleanup_duplicate_cache_images
    #cleanup_old_cache_images
  end
  
  def cleanup_duplicate_cache_images
    cache_images = get_all_cached_files
    
    #Don't delete the current cache image_path
    current_cache_image = CACHE_PATH + '/' + self.cached_filename
    cache_images.delete(current_cache_image)
    
    cache_images.each { |cache_image|
      File.delete cache_image
    }
  end
  
  def send_to_browser
    ActionController::Streaming.send_data @src_image.to_blob, :filename => @src_image.filename, 
                            :disposition => 'inline', 
                            :type => @src_image.mime_type
  end
end